package unipd.esp1112.pro;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

/**
 * activity where the user can precisely define his training building a sequence of activities, each one with 
 * its own limit, choosing between TIME, DISTANCE, CALORIES and PAUSE.
 * 
 * @author andrea basso, federico lancerin, alex tomasello
 *
 */

public class SuMisura extends Activity {

	/**
	 * variable to store the name of the profile the user is currently using.
	 */
	private String nome;
	/**
	 * button to go on to the next activity and start the training.
	 */
	private Button continua;
	/**
	 * button to add a training activity, pops up an alertdialog.
	 */
	private Button attivita;
	/**
	 * button to add a pause in the training process, pops up an alertdialog.
	 */
	private Button pausa;
	/**
	 * alertdialog that pops up when a training activity button is pressed, it always contains an edittext where the user has to
	 * input the limit he wants to reach with the training activity he is setting up.
	 * If the training activity is not PAUSA, the user has also to select it using a spinner.
	 */
	private AlertDialog.Builder builder;
	/**
	 * layout of the alertdialog, needed to manipulate its child.
	 */
	private View layout;	
	/**
	 * layoutinflater used to customize the layout of the alertdialog
	 */
	private LayoutInflater inflater;
	/**
	 * edittext contained in the alertdialog where the user input the desired limit
	 */
	private EditText limite;
	/**
	 * spinner contained in the alertdialog, not visible if the button that made the alertdialog appear was "pausa" because then the
	 * limit will forcibly intended in minutes.
	 */
	private Spinner scelte;
	/**
	 * arrayadapter used to customize the spinner
	 */
	private ArrayAdapter<CharSequence> adapter;
	/**
	 * textview contained in the alertdialog when the button that started it was "pausa", it contains a hint for the user.
	 */
	private TextView text;
	/**
	 * one instance of this button is added every time the user sets up a kind of training activity and add it to the sequence 
	 */
	private ActivityButton activityChoose;
	/**
	 * layout where buttons "activitychoose" are added, one for each training activity.
	 */
	private LinearLayout scrollActivity;
	/**
	 * ArrayList containing the actual sequence of training activities in a special form of Bunnons -> ActivityButton, inner class
	 * declared at the end of this document. 
	 */
	private ArrayList<ActivityButton> listaAttivita;
	/**
	 * variable to store the current context of the activity to pass it to newly created buttons.
	 */
	private Context mContext;
	/**
	 * int used to generate a unique key value for each "activityButton"
	 */
	private static int buttonKey;

	/*
	 * Classe che crea oggetti "pulsante" che si vanno ad aggiungere all'elenco.
	 * Nell'onClick, avviene la modifica del pulsante (Attività + valore) a
	 * seconda della scelta nella spinner e del valore scritto nell'editText.
	 */

	private class ActivityChoose implements OnClickListener {
		private ActivityButton activityChoose;

		private ActivityChoose(ActivityButton pC) {
			activityChoose = pC;
			activityChoose.setTypeface(null, Typeface.BOLD_ITALIC);
			activityChoose
					.setBackgroundResource(R.drawable.customcoloredbutton);
			activityChoose.setTextColor(Color.rgb(255, 255, 128));
		}

		@Override
		public void onClick(View v) {
			mContext = SuMisura.this;
			inflater = (LayoutInflater) mContext
					.getSystemService(LAYOUT_INFLATER_SERVICE);
			layout = inflater.inflate(R.layout.customdialog,
					(ViewGroup) findViewById(R.id.suMisura));
			adapter = ArrayAdapter.createFromResource(mContext,
					R.array.arrayscelte, android.R.layout.simple_spinner_item);
			adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			text = (TextView) layout.findViewById(R.id.dialogattivita);
			limite = (EditText) layout.findViewById(R.id.limite);
			scelte = (Spinner) layout.findViewById(R.id.scelte);
			text.setText("Scegli attività:");
			scelte.setAdapter(adapter);
			builder = new AlertDialog.Builder(mContext);
			builder.setView(layout);
			builder.setCancelable(false);

			// se sto editando una pausa, posso solo cambiarne la durata, non
			// editarla in attivita'.

			if (activityChoose.getText().toString().contains("Pausa")) {
				scelte.setVisibility(View.INVISIBLE);
				scelte.setClickable(false);
				text.setText("Scegli durata della pausa:");
			}

			// quando faccio "modifica" leggo il limite impostato e l'attività
			// selezionata e scrivo il tutto nell'oggetto activityChoose
			// cliccato in precedenza.

			builder.setPositiveButton("Modifica",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							String valore = limite.getText().toString();

							// se limite vuoto o con un numero impossibile,
							// segnala e torna indietro senza modifiche.

							if (valore.equalsIgnoreCase("")
									|| ((Long.parseLong(valore) < 1) || (Long
											.parseLong(valore) > 99999))) {
								limite.setHintTextColor(Color.RED);
								limite.setTextColor(Color.RED);
							} else {
								if (activityChoose.getText().toString()
										.contains("Pausa")) {
									activityChoose.setText("Pausa : " + valore
											+ " min");
									for (int i = 0; i < listaAttivita.size(); i++) {
										if (listaAttivita.get(i)
												.getKeyFromButton() == activityChoose
												.getKeyFromButton()) {
											listaAttivita.get(i)
													.setButtonActivityType(
															"Pausa");
											listaAttivita.get(i)
													.setButtonActivityLimit(
															valore);
										}
									}
								} else if (scelte.getSelectedItemPosition() == 0) {
									activityChoose.setText("Tempo : " + valore
											+ " min");
									for (int i = 0; i < listaAttivita.size(); i++) {
										if (listaAttivita.get(i)
												.getKeyFromButton() == activityChoose
												.getKeyFromButton()) {
											listaAttivita.get(i)
													.setButtonActivityType(
															"Tempo");
											listaAttivita.get(i)
													.setButtonActivityLimit(
															valore);
										}
									}
								} else if (scelte.getSelectedItemPosition() == 1) {
									activityChoose.setText("Distanza : "
											+ valore + " m");
									for (int i = 0; i < listaAttivita.size(); i++) {
										if (listaAttivita.get(i)
												.getKeyFromButton() == activityChoose
												.getKeyFromButton()) {
											listaAttivita.get(i)
													.setButtonActivityType(
															"Distanza");
											listaAttivita.get(i)
													.setButtonActivityLimit(
															valore);
										}
									}
								} else if (scelte.getSelectedItemPosition() == 2) {
									activityChoose.setText("Calorie : "
											+ valore + " Kcal");
									for (int i = 0; i < listaAttivita.size(); i++) {
										if (listaAttivita.get(i)
												.getKeyFromButton() == activityChoose
												.getKeyFromButton()) {
											listaAttivita.get(i)
													.setButtonActivityType(
															"Calorie");
											listaAttivita.get(i)
													.setButtonActivityLimit(
															valore);
										}
									}
								}
							}
						}
					});

			// se indietro, non fa nulla.

			builder.setNeutralButton("Indietro",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
						}
					});

			// elimina rimuove il pulsante dalla view.

			builder.setNegativeButton("Elimina",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							for (int i = 0; i < listaAttivita.size(); i++) {
								if (listaAttivita.get(i).getKeyFromButton() == activityChoose
										.getKeyFromButton())
									listaAttivita.remove(i);
							}
							scrollActivity.removeView(activityChoose);
						}
					});
			builder.create();
			builder.show();
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.sumisura);
		Intent intent = getIntent();
		if (intent != null)
			nome = intent.getStringExtra("profilo");
		buttonKey = 0;
		listaAttivita = new ArrayList<SuMisura.ActivityButton>();
		scrollActivity = (LinearLayout) findViewById(R.id.scrollActivity);
		attivita = (Button) findViewById(R.id.aggiungiAttivita);
		pausa = (Button) findViewById(R.id.aggiungiPausa);
		continua = (Button) findViewById(R.id.continuaPersonalizzato);

		if (savedInstanceState != null) {
			nome = savedInstanceState.getString("nome");
			String savedActivities[] = savedInstanceState
					.getStringArray("attivita");
			String savedValues[] = savedInstanceState.getStringArray("valori");
			for (int i = 0; i < savedActivities.length; i++) {
				ActivityButton savedActivityButton = new ActivityButton();
				savedActivityButton.setButtonActivityType(savedActivities[i]);
				savedActivityButton.setButtonActivityLimit(savedValues[i]);
				savedActivityButton.setOnClickListener(new ActivityChoose(
						savedActivityButton));
				savedActivityButton.setText(savedActivityButton
						.getTypeFromButton()
						+ " : "
						+ savedActivityButton.getLimitFromButton() + " ");
				if (savedActivityButton.getTypeFromButton().equalsIgnoreCase(
						"Pausa"))
					savedActivityButton.setText(savedActivityButton.getText()
							+ "min");
				if (savedActivityButton.getTypeFromButton().equalsIgnoreCase(
						"Tempo"))
					savedActivityButton.setText(savedActivityButton.getText()
							+ "min");
				if (savedActivityButton.getTypeFromButton().equalsIgnoreCase(
						"Distanza"))
					savedActivityButton.setText(savedActivityButton.getText()
							+ "m");
				if (savedActivityButton.getTypeFromButton().equalsIgnoreCase(
						"Calorie"))
					savedActivityButton.setText(savedActivityButton.getText()
							+ "Kcal");
				listaAttivita.add(savedActivityButton);
				scrollActivity.addView(savedActivityButton);
			}
		}
	};

	@Override
	public void onResume() {
		super.onResume();
		
		// Nell'"attività" avviene l'aggiunta di nuovi pulsanti "attività" alla
		// lista. Il pulsante viene "scritto" con la scelta fatta sulla spinner e il
		// limite inserito nell'editText

		attivita.setOnClickListener(new onActivityClickListener());

		// Nel "pausa" avviene l'aggiunta di nuovi pulsanti "pausa" alla lista.
		// Il pulsante viene "scritto" con il limite inserito nell'editText, lo
		// spinner è settato invisibile.

		pausa.setOnClickListener(new onPauseClickListener());

		continua.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				boolean activityConsistent = false;
				for (ActivityButton aButton : listaAttivita) {
					if (!(aButton.getTypeFromButton().equalsIgnoreCase("Pausa")))
						activityConsistent = true;
				}
				if (activityConsistent) {
					String attivita[] = new String[listaAttivita.size()];
					String valori[] = new String[listaAttivita.size()];
					for (int i = 0; i < listaAttivita.size(); i++) {
						attivita[i] = listaAttivita.get(i).getTypeFromButton();
						valori[i] = listaAttivita.get(i).getLimitFromButton();
					}
					Intent intent = new Intent(getApplicationContext(),
							MisurazioniSuMisura.class);
					intent.putExtra("profilo", nome);
					intent.putExtra("attivita", attivita);
					intent.putExtra("valori", valori);
					startActivity(intent);
					finish();
				} else {
					Toast toast = Toast.makeText(getApplicationContext(),
							"Nessuna Attività (non-pausa) Programmata",
							Toast.LENGTH_SHORT);
					toast.setGravity(Gravity.CENTER, 0, 0);
					toast.show();
				}
			}
		});
	}

	private class onActivityClickListener implements OnClickListener {
		@Override
		public void onClick(View v) {
			mContext = SuMisura.this;
			inflater = (LayoutInflater) mContext
					.getSystemService(LAYOUT_INFLATER_SERVICE);
			layout = inflater.inflate(R.layout.customdialog,
					(ViewGroup) findViewById(R.id.suMisura));
			adapter = ArrayAdapter.createFromResource(mContext,
					R.array.arrayscelte, android.R.layout.simple_spinner_item);
			adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			text = (TextView) layout.findViewById(R.id.dialogattivita);
			limite = (EditText) layout.findViewById(R.id.limite);
			scelte = (Spinner) layout.findViewById(R.id.scelte);
			scelte.setAdapter(adapter);
			builder = new AlertDialog.Builder(mContext);
			builder.setCancelable(false);
			builder.setView(layout);
			text.setText("Scegli l'attività da aggiungere:");
			builder.setPositiveButton("Aggiungi",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							String valore = limite.getText().toString();

							// se limite vuoto o con un numero impossibile,
							// segnala e torna indietro senza modifiche.

							if (valore.equalsIgnoreCase("")
									|| ((Long.parseLong(valore) < 1) || (Long
											.parseLong(valore) > 99999))) {
								limite.setHintTextColor(Color.RED);
								limite.setTextColor(Color.RED);
							} else {
								activityChoose = new ActivityButton();
								activityChoose
										.setOnClickListener(new ActivityChoose(
												activityChoose));
								if (scelte.getSelectedItemPosition() == 0) {
									activityChoose.setText("Tempo : " + valore
											+ " min");
									activityChoose
											.setButtonActivityType("Tempo");
									activityChoose
											.setButtonActivityLimit(valore);
									listaAttivita.add(activityChoose);
								}
								if (scelte.getSelectedItemPosition() == 1) {
									activityChoose.setText("Distanza : "
											+ valore + " m");
									activityChoose
											.setButtonActivityType("Distanza");
									activityChoose
											.setButtonActivityLimit(valore);
									listaAttivita.add(activityChoose);
								}
								if (scelte.getSelectedItemPosition() == 2) {
									activityChoose.setText("Calorie : "
											+ valore + " Kcal");
									activityChoose
											.setButtonActivityType("Calorie");
									activityChoose
											.setButtonActivityLimit(valore);
									listaAttivita.add(activityChoose);
								}
								scrollActivity.addView(activityChoose);
							}
						}
					});

			// se "indietro", non fa nulla.

			builder.setNegativeButton("Indietro",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
						}
					});
			builder.create();
			builder.show();
		}
	}

	private class onPauseClickListener implements OnClickListener {
		@Override
		public void onClick(View v) {
			mContext = SuMisura.this;
			inflater = (LayoutInflater) mContext
					.getSystemService(LAYOUT_INFLATER_SERVICE);
			layout = inflater.inflate(R.layout.customdialog,
					(ViewGroup) findViewById(R.id.suMisura));
			text = (TextView) layout.findViewById(R.id.dialogattivita);
			limite = (EditText) layout.findViewById(R.id.limite);
			scelte = (Spinner) layout.findViewById(R.id.scelte);
			text.setText("Scegli la durata della pausa:");
			scelte.setVisibility(View.INVISIBLE);
			scelte.setClickable(false);
			builder = new AlertDialog.Builder(mContext);
			builder.setCancelable(false);
			builder.setView(layout);
			builder.setPositiveButton("Aggiungi",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							String valore = limite.getText().toString();

							// se limite vuoto o con un numero impossibile,
							// segnala e torna indietro senza modifiche.

							if (valore.equalsIgnoreCase("")
									|| ((Long.parseLong(valore) < 1) || (Long
											.parseLong(valore) > 99999))) {
								limite.setHintTextColor(Color.RED);
								limite.setTextColor(Color.RED);
							} else {
								activityChoose = new ActivityButton();
								activityChoose
										.setOnClickListener(new ActivityChoose(
												activityChoose));
								activityChoose.setText("Pausa : " + valore
										+ " min");
								activityChoose.setButtonActivityType("Pausa");
								activityChoose.setButtonActivityLimit(valore);
								listaAttivita.add(activityChoose);
								scrollActivity.addView(activityChoose);
							}
						}
					});

			// se "indietro", non fa nulla.

			builder.setNegativeButton("Indietro",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
						}
					});
			AlertDialog dialog = builder.create();
			dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
			dialog.show();
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle savedInstanceState) {
		savedInstanceState.putString("nome", nome);
		String attivita[] = new String[listaAttivita.size()];
		String valori[] = new String[listaAttivita.size()];
		for (int i = 0; i < listaAttivita.size(); i++) {
			attivita[i] = listaAttivita.get(i).getTypeFromButton();
			valori[i] = listaAttivita.get(i).getLimitFromButton();
		}
		savedInstanceState.putStringArray("attivita", attivita);
		savedInstanceState.putStringArray("valori", valori);
	}
	
	/**
	 * ActivityButton inner class, a simple extension of the class Button where a button contains a unique key to identify him
	 * and a couple of parameters ( kind of training activity - limit chosen for this activity ) and their get and set methods.
	 */
	private class ActivityButton extends Button {

		private int indiceBott;
		private String tipoAtt;
		private String limiteImp;

		public ActivityButton() {
			super(getApplicationContext());
			tipoAtt = "undefined";
			limiteImp = "undefined";
			indiceBott = buttonKey++;
		}

		public String getTypeFromButton() {
			return tipoAtt;
		}

		public String getLimitFromButton() {
			return limiteImp;
		}

		public int getKeyFromButton() {
			return indiceBott;
		}

		public void setButtonActivityType(String type) {
			tipoAtt = type;
		}

		public void setButtonActivityLimit(String limit) {
			limiteImp = limit;
		}
	}
}
